from fastapi import APIRouter, Depends, status as HttpStatus, Response, Query
from sqlalchemy import and_
from db import get_db, crud, models
from schemas.flower import FlowerModel, CreateFlowerRequest, FlowerPagination, \
    UpdateFlowerRequest, FlowerOption, DeleteFlowerRequest, UpdateFlowerStatusRequest
from schemas.users import UserModel
from users.users import verify_token
from utils.response import HTTPException
from sqlalchemy.orm import Session
from datetime import datetime
from loguru import logger
from typing import Optional, List

router = APIRouter(prefix="/flower", tags=["鲜花管理"])


@router.post("", response_model=FlowerModel, response_model_exclude_none=True)
def create(data: CreateFlowerRequest, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    data.created_on = datetime.now()
    data.created_by = user.id
    return crud.Flower.create(db, data)


@router.get("",
            dependencies=[Depends(verify_token)],
            response_model=FlowerPagination,
            response_model_exclude_none=True)
def get_flower_pagination(
        page: int,
        page_size: int,
        kw: Optional[str] = None,
        presale: Optional[bool] = None,
        receiver: Optional[int] = None,
        material: Optional[int] = None,
        size: Optional[int] = None,
        flower_type: Optional[int] = Query(default=None, alias="type"),
        db: Session = Depends(get_db)):
    try:
        total, data = crud.Flower.gets(
            db=db,
            page=page - 1,
            page_size=page_size,
            kw=kw,
            receiver=receiver,
            material=material,
            size=size,
            flower_type=flower_type,
            presale=presale
        )

        return FlowerPagination(
            page=page,
            page_size=page_size,
            total=total,
            data=data
        )
    except Exception as err:
        logger.error(str(err))
        raise HTTPException(status_code=HttpStatus.HTTP_500_INTERNAL_SERVER_ERROR)


@router.get("/presale/all",
            dependencies=[Depends(verify_token)],
            response_model=List[FlowerModel],
            response_model_exclude_none=True)
def get_presale(db: Session = Depends(get_db)):
    flower_list = db.query(models.Flower).filter(and_(
        models.Flower.status != 0,
        models.Flower.presale == True
    )).all()

    return flower_list


@router.get("/presale/list",
            response_model=List[FlowerModel],
            response_model_exclude_none=True)
def get_presale(db: Session = Depends(get_db)):
    flower_list = db.query(models.Flower).filter(and_(
        models.Flower.status == 1,
        models.Flower.presale == True
    )).all()

    return flower_list


@router.get("/list", response_model=FlowerPagination, response_model_exclude_none=True)
def get_flower_list(
        page: int,
        page_size: int,
        sort: int,
        kw: Optional[str] = None,
        receiver: Optional[int] = None,
        material: Optional[int] = None,
        size: Optional[int] = None,
        flower_type: Optional[int] = Query(default=None, alias="type"),
        occasion: Optional[int] = None,
        db: Session = Depends(get_db)):
    try:
        total, data = crud.Flower.get_list(
            db=db,
            page=page - 1,
            page_size=page_size,
            sort=sort,
            kw=kw,
            receiver=receiver,
            material=material,
            size=size,
            flower_type=flower_type,
            occasion=occasion
        )
        return FlowerPagination(
            page=page,
            page_size=page_size,
            total=total,
            data=data
        )
    except Exception as err:
        logger.error(str(err))
        raise HTTPException(status_code=HttpStatus.HTTP_500_INTERNAL_SERVER_ERROR)


@router.get("/items",
            dependencies=[Depends(verify_token)],
            response_model=List[FlowerOption],
            response_model_exclude_none=True)
def get_flower_items(db: Session = Depends(get_db)):
    return crud.Flower.get_items(db)


@router.put("", response_model=FlowerModel, response_model_exclude_none=True)
def update(data: UpdateFlowerRequest, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    data.created_on = datetime.now()
    data.created_by = user.id
    crud.Flower.update(db, data)

    return Response()


@router.patch("/status")
def update_flower_status(data: UpdateFlowerStatusRequest, user: UserModel = Depends(verify_token),
                         db: Session = Depends(get_db)):
    db.query(models.Flower).filter_by(id=data.id).update({
        "updated_on": datetime.now(),
        "updated_by": user.id,
        "status": data.status
    })
    db.commit()


@router.delete("/{flower_id}", dependencies=[Depends(verify_token)], response_model_exclude_none=True)
def delete(flower_id: int, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    crud.Flower.delete(db, DeleteFlowerRequest(
        id=flower_id,
        updated_on=datetime.now(),
        updated_by=user.id
    ))
    return Response()


@router.get("/detail/{flower_id}", response_model=FlowerModel, response_model_exclude_none=True)
def get_flower_detail(flower_id: int, db: Session = Depends(get_db)):
    flower = db.query(models.Flower).get(flower_id)
    if flower is not None:
        flower.views_count += 1
        db.commit()
        return flower

    raise HTTPException(status_code=404)


@router.get("/stats")
def stats(db: Session = Depends(get_db)):
    data = db.query(
        models.Flower.id,
        models.Flower.name,
        models.Flower.views_count,
        models.Flower.sales_count
    ).filter(and_(
        models.Flower.status.in_([1, 2])
    )).all()

    return [
        {
            "id": item.id,
            "name": item.name,
            "views_count": item.views_count,
            "sales_count": item.sales_count,
        } for item in data
    ]
